﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArithmeticLibrary.Tree;

namespace ArithmeticLibrary.Visitors
{
    /// <summary>
    /// Visitor pro tisk vyrazu v infixovem tvaru (se zavorkami).
    /// </summary>
    class InfixPrinterVisitor : IExpressionVisitor<StringBuilder, StringBuilder>
    {
        public StringBuilder Visit(NumberNode node, StringBuilder context)
        {
            context.Append(node.Value);

            return context;
        }

        public StringBuilder Visit(VariableNode node, StringBuilder context)
        {
            context.Append(node.Name);

            return context;
        }
        
        public StringBuilder Visit(UnaryMinusNode node, StringBuilder context)
        {
            context.Append("-(");

            node.Child.Accept(this, context);

            context.Append(")");

            return context;
        }

        public StringBuilder Visit(SineNode node, StringBuilder context)
        {
            context.Append("sin(");

            node.Child.Accept(this, context);

            context.Append(")");

            return context;
        }

        public StringBuilder Visit(CosineNode node, StringBuilder context)
        {
            context.Append("cos(");

            node.Child.Accept(this, context);

            context.Append(")");

            return context;
        }

        public StringBuilder Visit(TangentNode node, StringBuilder context)
        {
            context.Append("tan(");

            node.Child.Accept(this, context);

            context.Append(")");

            return context;
        }

        public StringBuilder Visit(LogarithmNode node, StringBuilder context)
        {
            context.Append("log(");

            node.Child.Accept(this, context);

            context.Append(")");

            return context;
        }

        public StringBuilder Visit(ExponentialNode node, StringBuilder context)
        {
            context.Append("exp(");

            node.Child.Accept(this, context);

            context.Append(")");

            return context;
        }

        public StringBuilder Visit(PlusNode node, StringBuilder context)
        {
            context.Append('(');
            node.Left.Accept(this, context);
            context.Append('+');
            node.Right.Accept(this, context);
            context.Append(')');

            return context;
        }

        public StringBuilder Visit(MinusNode node, StringBuilder context)
        {
            context.Append('(');
            node.Left.Accept(this, context);
            context.Append('-');
            node.Right.Accept(this, context);
            context.Append(')');

            return context;
        }

        public StringBuilder Visit(MultiplyNode node, StringBuilder context)
        {
            context.Append('(');
            node.Left.Accept(this, context);
            context.Append('*');
            node.Right.Accept(this, context);
            context.Append(')');

            return context;
        }

        public StringBuilder Visit(DivideNode node, StringBuilder context)
        {
            context.Append('(');
            node.Left.Accept(this, context);
            context.Append('/');
            node.Right.Accept(this, context);
            context.Append(')');

            return context;
        }

        public StringBuilder Visit(PowerNode node, StringBuilder context)
        {
            context.Append('(');
            node.Left.Accept(this, context);
            context.Append(")^(");
            node.Right.Accept(this, context);
            context.Append(')');

            return context;
        }

        public string ExpressionToString(Node node)
        {
            return node.Accept(this, new StringBuilder()).ToString();
        }
    }

}
